<template>
  <div class="app-container" :style="{height:containerHeight+'px',padding:'10px !important'}"  @click="OptionCardClose">
    <div class="headbox">
      <div class="page-desc">
        <div style="display: inline-block;margin-right: 10px;">
          <el-popover
            placement="bottom-end"
            trigger="hover"
            content="右键左侧菜单树菜单选择新建目录/菜单，或者选择右侧表格中的行，再选择左侧菜单树对应树菜单，点击添加，系统会自动创建菜单，并生成增、删、改、查等功能">
            <span class="page-desc-title "slot="reference">
              批量新增菜单:<i class="el-icon-info"></i>
            </span>
          </el-popover>
        </div>
        <div style="display: inline-block;margin-right: 10px;">
          <el-popover
            placement="bottom-end"
            trigger="hover"
            content="如果希望生成的表单中的组件类型和验证方式符合你的预期，那么在数据库表创建过程中请遵循相应规则。">
            <span class="page-desc-title "slot="reference">
              自动生成表单:<i class="el-icon-info"></i>
            </span>
          </el-popover>
        </div>
        <div style="display: inline-block;margin-right: 10px;">
          <el-popover
            placement="bottom-end"
            trigger="hover"
            content="自动生成后端增删改查功能的优树搭程序，无需编译，支持在线修改后端程序。也可以在后续切换为若依原生的自动生成后端代码程序方式。">
            <span class="page-desc-title "slot="reference">
              自动生成程序:<i class="el-icon-info"></i>
            </span>
          </el-popover>
        </div>
        <div style="display: inline-block;margin-right: 10px;">
          <el-popover
              placement="top-start"
              trigger="hover">
              <div style="height: 400px;overflow: auto;">
                <p cid="n4" mdtype="paragraph"><span md-inline="plain">自动创建表单功能需要根据 </span>
                	<span md-inline="strong"><strong><span md-inline="plain">注释</span></strong></span>
                	<span md-inline="plain"> 信息获取字段中文名和值集数据，创建规则如下：</span></p>
                <h3 cid="n41" mdtype="heading">
                	<span md-inline="strong"><strong><span md-inline="plain">对于表名注释</span></strong></span></h3>
                <p cid="n53" mdtype="paragraph">
                	<span md-inline="strong"><strong><span md-inline="plain">格式：</span></strong></span></p>
                <p cid="n45" mdtype="paragraph">
                	<span md-inline="plain">表中文名__表注释信息</span></p>
                <p cid="n45" mdtype="paragraph"><strong>规则：</strong> </p>
                <p cid="n69" mdtype="paragraph">
                	<span md-inline="plain">通过双英文下划线分割"__"表中文名与表注释信息</span></p>
                <p cid="n43" mdtype="paragraph">
                	<span md-inline="plain">注：表中文名将用于默认菜单</span></p>
                <h3 cid="n50" mdtype="heading"><span md-inline="strong"><strong>
                	<span md-inline="plain">对于字段注释</span></strong></span></h3>
                <p cid="n14" mdtype="paragraph"><span md-inline="strong"><strong>
                	<span md-inline="plain">格式：</span></strong></span></p>
                <p cid="n19" mdtype="paragraph">
                	<span md-inline="plain">中文字段名__字段注释在前面S[1: 是_0:否-1:其他]”;</span></p>
                <p cid="n21" mdtype="paragraph">
                	<span md-inline="plain">中文字段名__S[1: 是_0:否-1:其他]字段注释在后面”。</span></p>
                <p cid="n24" mdtype="paragraph"><span md-inline="plain"> </span>
                	<span md-inline="strong">
                		<strong><span md-inline="plain">规则</span></strong></span>
                	<span md-inline="plain"> ：</span></p>
                <p cid="n24" mdtype="paragraph"> 通过双英文下划线分割"__"字段中文名与字段注释信息</p>
                <p cid="n24" mdtype="paragraph"> 可以在字段注释信息中添加当前字段的值集关系： </p>
                <p cid="n27" mdtype="paragraph"><span md-inline="plain">S [..选项值..]表示下拉框 </span></p>
                <p cid="n29" mdtype="paragraph"><span md-inline="plain">R [..选项值..]表示单选框 </span></p>
                <p cid="n31" mdtype="paragraph"><span md-inline="plain">C [..选项值..]表示复选框 </span></p>
                <p cid="n33" mdtype="paragraph">
                	<span md-inline="strong"><strong>
                		<span md-inline="plain">选项值：</span></strong></span></p>
                <p cid="n35" mdtype="paragraph">
                	<span md-inline="plain">以单英文下划线“_”分割多个选项，每个选项以”:“分隔值与描述。</span></p>
              </div>
              <span class="page-desc-title "slot="reference">
                数据表创建规则:<i class="el-icon-info"></i>
              </span>
            </el-popover>
        </div>
      </div>
      <div style="display:flex;flex-wrap:nowrap;justify-content:end;margin-bottom: 5px;">
        <el-input style="width:180px" v-model="tablePre" @change="searchTable" placeholder="请输入表前缀"></el-input>
        <el-button style="margin-left: 10px;" type="primary" @click="searchTable">搜索</el-button>
        <el-button style="margin-left: 10px;" type="primary" @click="saveTree">保存</el-button>
      </div>
    </div>
    <el-row style="height: 100%;width: 100%;">
      <el-col :span="5" :style="{height:containerHeight-55+'px',position:'relative',scrollbarWidth: 'none',border:'1px solid lightgrey',borderRight:'0',paddingTop:'43px'}">
        <div class="treeBtn">
          <span>菜单</span>
          <div style="display: inline-block;font-size: 16px;">
            <el-button class="treeOperBtn" type="text" icon="el-icon-caret-bottom" @click="expandAll(treeData)"></el-button>
            <el-button class="treeOperBtn" type="text" icon="el-icon-caret-top" @click="collapseAll(treeData)"></el-button>
          </div>
        </div>
        <div :style="{height:containerHeight-98+'px',overflow:'auto'}">
          <el-tree
            :data="treeData"
            node-key="menuId"
            default-expand-all
            draggable
            highlight-current
            :allow-drop="allowDrop"
            @node-contextmenu="floderOption"
            ref="leftTree">
            <span slot-scope="{ node, data }" style="width: 100%;" >
              <svg-icon
                v-if="data.icon"
                slot="prefix"
                :icon-class="data.icon"
                style="width: 25px;"
              />
              <span>{{ data.menuName }}</span>
            </span>
          </el-tree>
        </div>

        <div :style="{'z-index': 9999, position: 'fixed',left: optionCardX + 'px',
        				top: optionCardY + 'px', width: '120px', background: 'white',
        				 'box-shadow': '0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .04)'}"
        	v-show="optionCardShow" id="option-button-group">
          <el-button @click="addMenu" class="option-card-button">新建目录</el-button>
          <el-button @click="addNewEmptyMenu" class="option-card-button">新建菜单</el-button>
          <el-button @click="synchronization()" class="option-card-button">同步表结构</el-button>
          <el-button @click="editNode" class="option-card-button">编辑</el-button>
        	<el-button @click="remove" class="option-card-button">删除</el-button>
        </div>
        <el-dialog title="菜单编辑"
                   width="30%"
                   :close-on-click-modal="notClickModal"
                   :visible.sync="editNodeVisible">
          <div style="margin-top: 10px;">
            <span style="display: inline-block;width: 80px;">菜单名：</span>
            <el-input style="width: 240px;" v-model="nodeName"></el-input>
          </div>
          <div style="margin-top: 10px;height: 36px;display: flex;align-items: center;">
            <span style="display: inline-block;width: 80px;">图 标：</span>
            <div style="width:240px;height:36px;line-height:36px;display: inline-block;text-align: center;font-size: 16px;border: 1px solid lightgrey;border-radius: 5px;">
              <el-popover
                placement="bottom-start"
                width="600"
                trigger="click"
                @show="$refs['iconSelect'].reset()"
              >
                <IconSelect ref="iconSelect" @selected="selected" :active-icon="chooseIcon" />
                <el-input slot="reference" v-model="chooseIcon" placeholder="点击选择图标" readonly>
                  <svg-icon
                    v-if="chooseIcon"
                    slot="prefix"
                    :icon-class="chooseIcon"
                    style="width: 25px;"
                  />
                  <i v-else slot="prefix" class="el-icon-search el-input__icon" />
                </el-input>
              </el-popover>
            </div>
            <i v-if="chooseIcon" class="el-icon-error" style="color:darkgrey;font-size:18px;cursor: pointer;" @click="clearIcon"/>
          </div>
          <div style="margin-top: 20px;">
            <span style="display: inline-block;width: 80px;">隐 藏：</span>
            <el-switch
              v-model="visible"
              active-value="1"
              inactive-value="0"
              active-color="#13ce66"
              inactive-color="#7F7F7F">
            </el-switch>
          </div>
          <div slot="footer" class="dialog-footer">
            <el-button @click="preTreeNode">上一个</el-button>
            <el-button @click="nextTreeNode">下一个</el-button>
            <el-button type="primary" @click="confirmEditNode">完 成</el-button>
          </div>
        </el-dialog>
        <el-dialog
          title="新建目录"
          :visible.sync="newMenuVisible"
          width="30%">
          <div style="margin-top: 10px;">
            <span style="display: inline-block;width: 80px;">目录名：</span>
            <el-input style="width: 240px;" v-model="menuName" @input="menuNameInput"@keyup.enter.native="confirmAdd()"></el-input>
          </div>
          <div style="margin-top: 10px;">
            <span style="display: inline-block;width: 80px;">路由：</span>
            <el-input style="width: 240px;" v-model="routerPath"></el-input>
          </div>
          <span slot="footer" class="dialog-footer">
            <el-button @click="cancelAdd">取 消</el-button>
            <el-button type="primary" @click="confirmAdd()">确 定</el-button>
          </span>
        </el-dialog>
      </el-col>
      <!-- <el-col :span="2" class="middle-transfer-btn">
        <el-button type="primary" @click="addItemToTree()">添加</el-button>
      </el-col> -->
      <el-col :span="19">
        <el-dialog
          title="批量CRUD"
          :visible.sync="createCrud"
          :close-on-click-modal="notClickModal"
          width="30%">
          <div style="padding-top: 10px;">
            <div class="tipStyle" :style="tipMessage=='执行失败' ? 'color:red':'color:black'"><i class="el-icon-tickets iconStyle"></i>{{tipMessage}}</div>
            <div style="margin-top: 5px;margin-left: 20px;" :class="stepIndex > 1 ? 'activeStep':''">1、{{saveMessage}}<i v-show="stepIndex>1" class="el-icon-success"></i></div>
            <div style="margin-top: 5px;margin-left: 20px;" :class="stepIndex > 2 ? 'activeStep':''">2、{{loadingMessage}}<i v-show="stepIndex>2 && !errorType" class="el-icon-success"></i></div>
            <div :style="stepIndex>3 && errorType ? 'color:red;margin-top: 5px;margin-left: 20px;' : 'margin-top: 5px;margin-left: 20px;'" :class="stepIndex > 3 ? 'activeStep':''">3、{{submitMessage}}<i v-show="stepIndex>3 && !errorType" class="el-icon-success"></i><i v-show="stepIndex>3 && errorType" style="color: red;" class="el-icon-warning"></i></div>
          </div>
          <span slot="footer" class="dialog-footer" v-show="!errorType">
            <el-button type="primary" plain v-show="!isSavingBtn" @click="cancelRetry">取 消</el-button>
            <el-button type="primary" v-show="!isSavingBtn" @click="continueOperate">继 续</el-button>
            <el-button type="primary" v-show="isSavingBtn && !isFinish" disabled>执行中</el-button>
            <el-button type="primary" v-show="isSavingBtn && isFinish" @click="confirmFinish">确 认</el-button>
          </span>
          <span slot="footer" class="dialog-footer" v-show="errorType">
            <el-button type="primary" @click="retrysaveTree">重 试</el-button>
            <el-button type="primary" @click="cancelRetry">确 认</el-button>
          </span>
        </el-dialog>
        <el-table
          :data="tableData"
          v-loading="loading"
          highlight-current-row
          :row-class-name="tableRowClassName"
          border
          @current-change="handleCurrentChange"
          :height="containerHeight-95"
          :key="Math.random()"
          style="width: 100%;overflow:'auto'">
          <el-table-column
            fixed="left"
            label="生成CRUD"
            align="center"
            width="100">
            <template slot-scope="scope">
              <el-button style="font-size: 16px;font-weight: bold;" icon="el-icon-arrow-left" @click="addItemToTree(scope.row)" type="text" size="medium" title="向菜单增加此增删改查（CRUD）功能"></el-button>
              <!-- <el-button v-show="usedNode.includes(scope.row.tableName)" style="font-size: 16px;color:red;font-weight: bold;" icon="el-icon-arrow-right" @click="removeTreeItem(scope.row)" type="text" size="medium" title="从菜单中删除该CRUD 映射功能"></el-button> -->
            </template>
          </el-table-column>
          <el-table-column
            fixed="left"
            label="字段"
            align="center"
            width="100">
            <template slot-scope="scope">
              <div style="width: 100%;height: 40px;" @mouseover="showPop(scope.row.tableName)">
                <el-button v-if="showPopCondition!=scope.row.tableName" style="font-size: 16px;" type="text" icon="el-icon-more"></el-button>
                <PopoverItem :data="scope.row.columns" v-if="showPopCondition==scope.row.tableName" :height="containerHeight-100"></PopoverItem>
              </div>
            </template>
          </el-table-column>
          <el-table-column
            fixed="left"
            align="center"
            width="120">
            <template slot="header" slot-scope="scope">
              <span title="当表结构发生变化后，进行同步操作">同步表结构<i class="el-icon-question"></i></span>
            </template>
            <template slot-scope="scope">
              <a style="font-size: 12px;text-decoration: underline;" @click="synchronization(scope.row)" title="当表结构发生变化后，进行同步操作">同 步</a>
            </template>
          </el-table-column>
          <el-table-column
            fixed
            prop="tableName"
            label="表英文名"
            width="200">
          </el-table-column>
          <el-table-column
            prop="tableComment"
            label="表中文(菜单名)"
            width="200">
          </el-table-column>
          <el-table-column
            prop="tableRemark"
            label="表描述">
          </el-table-column>
        </el-table>
        <div style="width: 100%;height: 40px;display: flex;justify-content: end;">
          <el-pagination
            @current-change="changePage"
            :current-page="currentPage"
            :page-size="10"
            layout="total, prev, pager, next, jumper"
            :total="total">
          </el-pagination>
        </div>
      </el-col>
    </el-row>
  </div>
</template>

<script>
import PopoverItem from "./popOverItem.vue"
import { FormItem } from "element-ui";
import {getMenus,getDatabaseTableList,saveMenuTree,saveFormbuild} from "../../api/BaseApi.js";
import {FormBuildInitDrawing} from "@/views/youshuda/components/FormBuild/js/FormBuildInitDrawing";
import { synchDb } from "@/api/tool/gen";
import IconSelect from "@/components/IconSelect";
import pinyin from "@/views/youshuda/utils/pinyin"

export default {
  name: 'navmenuSet',
  mixins: [FormBuildInitDrawing],
  components:{
    PopoverItem,
    IconSelect
  },
  data() {
    return {
      optionCardX: '',// 文件夹节点操作卡位置
      optionCardY:'',
      optionCardShow: false,// 文件夹节点操作卡是否显示
      optionData: [],// 右键选中的节点的data
      node: {},// 当前右键选中的节点信息
      tree: null,
      treeData: [],
      childrenData:[],//缓存所有树节点
      usedNode:[],
      needGenFrom:[],
      tableData: [],
      storageTableData:[],
      loading:false,
      containerHeight:'',
      menuType:'主菜单',
      tablePre:'',
      newMenuVisible:false,
      menuName:'',
      routerPath:'',
      createCrud:false,//批量crud弹框
      tipMessage:"即将执行批量CRUD生成 是否继续?",
      saveMessage:'CRUD初始化 等待执行',
      loadingMessage:'生成表单 等待执行',
      submitMessage:'提交表单数据 等待执行',
      storageNodeData:[],
      needGenFromData:[],
      currentRow:{},
      notClickModal:false,
      stepIndex:0,
      errorType:false,
      isSavingBtn:false,
      isFinish:false,
      showPopCondition:'',
      currentPage:1,
      pageSize:10,
      total:0,
      chooseIcon:'',
      editNodeVisible:false,
      nodeName:'',
      visible:'0',//是否隐藏 0--显示 1--隐藏
    }
  },
  mounted() {
    this.containerHeight=document.getElementsByClassName('app-main')[0].clientHeight;
    getMenus().then(res=>{
      let tree=[
        {
          menuName:'根节点',
          children:res.data.menus,
          menuId:'Root',
          menuType:"M"
        }
      ]
      this.treeData=tree;
      this.usedNode=res.data.usedTableInfo;
      this.needGenFrom=res.data.needGenFrom;
    })
  },
  methods: {
    showPop(data){
      this.showPopCondition=data;
    },
    tableRowClassName(row, index) {
      let className="";
      return className;
    },
    // 将数据库表添加到菜单树
    addItemToTree(row){
      let self = this;
      let nowNode=this.$refs.leftTree.getCurrentNode();
      if(nowNode){
        let data={
          menuName:row.tableComment,
          bindTable:row.tableName,
          operType:"A",
          menuType:'C',
          menuId:Date.now(),
          icon:'#'
        }
        if(nowNode.menuType=="M"){
          this.$refs.leftTree.append(data,nowNode.menuId);
          self.treeData.forEach((item,index) => {
            if(nowNode.menuId==item.menuId){
              self.$refs.leftTree.store.nodesMap[item.menuId].expanded = true;
              setTimeout(()=>{
                self.scrollToNode()
              },400)
            }
            item.children && item.children.length > 0
              ? self.expandAll(item.children,nowNode.menuId)
              : ""; // 子级递归
          });
        }else{
          self.$refs.leftTree.insertAfter(data,nowNode.menuId);
          self.treeData.forEach((item,index) => {
            if(nowNode.menuId==item.menuId){
              self.$refs.leftTree.store.nodesMap[item.menuId].expanded = true;
              setTimeout(()=>{
                self.scrollToNode()
              },400)
            }
            item.children && item.children.length > 0
              ? self.expandAll(item.children,nowNode.menuId)
              : ""; // 子级递归
          });
        }
        this.$refs.leftTree.setCurrentNode(data);
        this.usedNode.push(row.tableName)

      }else{
        this.$message({
          type: 'warning',
          message: '请先点击左侧菜单树选择您要添加到的节点'
        })
      }
    },
    removeNode (nodes, tableName){
      for (let i = 0; i < nodes.length; i++) {
        if (nodes[i].bindTable === tableName) {
          nodes.splice(i, 1);
          return true;
        }
        if (nodes[i].children && nodes[i].children.length > 0) {
          if (this.removeNode(nodes[i].children, tableName)) {
            return true;
          }
        }
      }
      return false;
    },
    removeTreeItem(data){
      this.$confirm('是否确认要从菜单中删除此表的增删改查（CRUD）功能？', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
      }).then(()=>{
        this.removeNode(this.treeData, data.tableName);
        this.usedNode=this.usedNode.filter(item => item != data.tableName)
      })
    },
    // 文件夹右键时触发的事件
    floderOption(e, data, n, t) {
      this.$refs.leftTree.setCurrentNode(data);
    	this.optionCardShow = false
    	this.optionCardX = e.x   // 让右键菜单出现在鼠标右键的位置
      if(e.y > 430){
        this.optionCardY = e.y - 180
      }else{
        this.optionCardY = e.y
      }
    	this.optionData = data
    	this.node = n // 将当前节点保存
    	this.tree = t
    	this.optionCardShow = true  // 展示右键菜单
    },
    // 新建目录
    addMenu(){
      this.optionCardShow = false
      if(this.node){
        this.newMenuVisible=true;
      }
    },
    // 输入目录名自定添加路由（拼音）
    menuNameInput(value){
      // const options = {
      //   style: 'normal', // 普通风格，不带声调
      //   heteronym: false // 无多音字模式
      // };
      // let result = pinyin.chineseToPinYin(value, options).join('');
      let result = pinyin.chineseToPinYin(value);
      this.routerPath=result;
    },
    cancelAdd(){
      this.newMenuVisible=false;
      this.menuName="";
      this.routerPath="";
    },
    confirmAdd(){
      let self=this;
      let nowMenuId=Date.now()
      let data={
        menuName: this.menuName,
        menuType:'M',
        operType:"A",
        path:this.routerPath,
        menuId:nowMenuId,
        icon:'#'
      }
      if(this.routerPath==''){
        this.$message({
          type:"warning",
          message:"请输入路由"
        })
        return;
      }
      if(this.menuName==''){
        this.$message({
          type:"warning",
          message:"请输入目录名"
        })
        return;
      }
      if(this.node.data.menuType=="M"){
        this.$refs.leftTree.append(data,this.node.data.menuId);
      }else{
        this.$refs.leftTree.insertAfter(data,this.node.data.menuId);
      }
      this.$refs.leftTree.setCurrentKey(nowMenuId);
      self.treeData.forEach((item,index) => {
        if(self.node.data.menuId==item.menuId){
          self.$refs.leftTree.store.nodesMap[item.menuId].expanded = true;
          setTimeout(()=>{
            self.scrollToNode()
          },400)
        }
        item.children && item.children.length > 0
          ? self.expandAll(item.children,this.node.data.menuId)
          : ""; // 子级递归
      });
      this.newMenuVisible=false;
      this.menuName="";
      this.routerPath="";
    },
    // 新增空菜单
    addNewEmptyMenu(){
      let self=this;
      this.optionCardShow = false
      let nowMenuId=Date.now();
      if(this.node){
        this.$prompt('请输入菜单名称', '提示', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
        }).then(({ value }) => {
          let data={
            menuName: value,
            menuType:'C',
            operType:"A",
            menuId:nowMenuId,
            icon:'#'
          }
          if(this.node.data.menuType=="M"){
            this.$refs.leftTree.append(data,this.node.data.menuId);
          }else{
            this.$refs.leftTree.insertAfter(data,this.node.data.menuId);
          }
          this.$refs.leftTree.setCurrentKey(nowMenuId);
          self.treeData.forEach((item,index) => {
            if(this.node.data.menuId==item.menuId){
              self.$refs.leftTree.store.nodesMap[item.menuId].expanded = true;
              setTimeout(()=>{
                self.scrollToNode()
              },400)
            }
            item.children && item.children.length > 0
              ? self.expandAll(item.children,this.node.data.menuId)
              : ""; // 子级递归
          });
        }).catch(() => {
          this.$message({
            type: 'info',
            message: '取消输入'
          });
        });
      }
    },
    // 同步
    synchronization(option){
      let bindTable="";
      if(option){
        bindTable=option.tableName;
      }else{
        this.optionCardShow=false
        if(this.node.data.bindTable){
          bindTable=this.node.data.bindTable;
        }
      }
      synchDb(bindTable).then(res=>{
        if(res.code==200){
          this.$message({
            type:"success",
            message:'同步成功'
          })
        }else{
          this.$message({
            type:"error",
            message: res.msg
          })
        }
      })
    },
    // 编辑菜单
    editNode(){
      this.optionCardShow = false;
      let nowNode=this.$refs.leftTree.getCurrentNode();
      this.node=nowNode;
      this.editNodeVisible=true;
      this.nodeName=this.node.menuName;
      this.visible=this.node.visible;
      if(this.node.icon && this.node.icon!="#"){
        this.chooseIcon=this.node.icon
      }else{
        this.chooseIcon=""
      }
    },
    // 选择图标
    selected(name) {
      this.chooseIcon=name;
    },
    // 清除图标
    clearIcon(){
      this.chooseIcon="";
    },
    // 确认修改菜单信息
    confirmEditNode(){
      let nowNode=this.$refs.leftTree.getCurrentNode();
      if(this.nodeName==""){
        this.$message({
          type:"warning",
          message:"请输入菜单名"
        })
        return;
      }
      nowNode.menuName = this.nodeName;
      nowNode.icon = this.chooseIcon;
      nowNode.visible = this.visible;
      this.editNodeVisible=false;
      this.nodeName="";
      this.visible="0";
    },
    // 获取当前选择菜单上一个菜单
    getAdjacentNode(treeData, currentNode, direction) {
        let stack = [...treeData]; // 复制一份原始数据作为栈
        let prevNode = null;
        let nextNode = null;
        while (stack.length > 0) {
            let node = stack.shift();
            if (node === currentNode) {
                if (direction === 'prev') return prevNode;
                else if (direction === 'next') return nextNode;
            }
            prevNode = node;
            if (node.children && node.children.length) {
                stack.unshift(...node.children);
            } else {
                nextNode = null; // 如果没有子节点，则重置 nextNode
            }
        }
        return null; // 如果找不到相邻节点，则返回 null
    },
    preTreeNode(){
      let nowNode=this.$refs.leftTree.getCurrentNode();
      let prevNode=this.getAdjacentNode(this.treeData,nowNode,'prev')
      if(prevNode){
        if(this.nodeName!=""){
          nowNode.menuName = this.nodeName;
          this.nodeName="";
        }
        nowNode.icon = this.chooseIcon;
        nowNode.visible=this.visible;
        this.node=prevNode;
        this.editNodeVisible=true;
        this.nodeName=this.node.menuName;
        if(this.node.icon && this.node.icon!="#"){
          this.chooseIcon=this.node.icon
        }else{
          this.chooseIcon=""
        }
        this.visible=prevNode.visible;
        this.$refs.leftTree.setCurrentNode(prevNode)
        this.scrollToNode()
      }else{
        this.$message({
          type:'warning',
          message: '当前菜单已为最上面菜单',
        })
      }
    },
    getAllNodes(treeData){
      let self=this;
      treeData.forEach((item,index) => {
        this.childrenData.push(item)
        item.children && item.children.length > 0
          ? self.getAllNodes(item.children)
          : ""; // 子级递归
      });

    },
    nextTreeNode(){
      let nowNode=this.$refs.leftTree.getCurrentNode();
      this.getAllNodes(this.treeData);
      let nextNode;
      this.childrenData.forEach((item,index)=>{
        if(item.menuId==nowNode.menuId){
          nextNode=this.childrenData[index+1]
        }
      })
      if(nextNode){
        if(this.nodeName!=""){
          nowNode.menuName = this.nodeName;
          this.nodeName="";
        }
        nowNode.icon = this.chooseIcon;
        nowNode.visible=this.visible;
        this.node=nextNode;
        this.editNodeVisible=true;
        this.nodeName=this.node.menuName;
        if(this.node.icon && this.node.icon!="#"){
          this.chooseIcon=this.node.icon
        }else{
          this.chooseIcon=""
        }
        this.visible=nextNode.visible;
        this.$refs.leftTree.setCurrentNode(nextNode)
        this.scrollToNode()
      }else{
        this.$message({
          type:'warning',
          message: '当前菜单已为最下面菜单',
        })
      }
    },
    // 删除菜单
    remove() {
      this.optionCardShow = false
      // 判断该节点是否有子节点
      if (this.node.childNodes.length != 0) {
          this.$message({
              message: '该菜单下存在子菜单，不允许直接删除',
              type: 'warning'
          });
          return;
      }else{
        this.$refs.leftTree.remove(this.node.data)
        this.usedNode=this.usedNode.filter(item => item != this.node.data.bindTable)
      }
    },
    // 拖动节点限制条件
    allowDrop(draggingNode, dropNode, type) {
      if (dropNode.data.menuType === 'C') {
        return type !== 'inner';
      } else {
        return true;
      }
    },
    handleCurrentChange(val) {
      this.currentRow = val;
    },
    // 根据条件查询数据库表
    searchTable(){
      if(this.tablePre==""){
        this.$message({
            message: '请输入查询条件',
            type: 'warning'
        });
        return;
      }
      let params={
        tableName:this.tablePre,
        pageNum:1,
        pageSize: 10
      }
      this.loading=true;
      getDatabaseTableList(params).then(res=>{
        this.storageTableData=res.rows;
        this.total=res.total;
        this.storageTableData.forEach(item=>{
          this.usedNode.forEach(item2=>{
            if(item.tableName==item2){
              item.disabled=true;
            }
          })
        })
        this.tableData=this.storageTableData;
        this.loading=false;
      })
    },
    changePage(val){
      if(this.tablePre==""){
        this.$message({
            message: '请输入查询条件',
            type: 'warning'
        });
        return;
      }
      let params={
        tableName:this.tablePre,
        pageNum:val,
        pageSize: 10
      }
      this.loading=true;
      getDatabaseTableList(params).then(res=>{
        this.storageTableData=res.rows;
        this.total=res.total
        this.storageTableData.forEach(item=>{
          this.usedNode.forEach(item2=>{
            if(item.tableName==item2){
              item.disabled=true;
            }
          })
        })
        this.tableData=this.storageTableData;
        this.loading=false;
      })
    },
    // 保存菜单树
    saveTree(){
      this.createCrud=true;
    },
    continueOperate(){
      this.isSavingBtn=true;
      let dataVal=this.treeData[0].children;
      saveMenuTree(dataVal).then(res=>{
        if(res.code==200){
          this.needGenFromData=res.data.needGenFrom
          this.stepIndex=1;
          if(this.needGenFromData.length>0){
            this.tipMessage="正在执行 请稍等"
            this.saveMessage="CRUD初始化 执行完成"
            let CRUDJsonData=this.needGenFromData
            if(CRUDJsonData.length>0){
              let hasError=false;
              this.stepIndex=2
              for(let i=0;i<CRUDJsonData.length;i++){
                try{
                  let result = this.generateDrawingList(CRUDJsonData[i].formBuildKey,CRUDJsonData[i].columns)
                  CRUDJsonData[i].fromBuildConfig=result;
                  let newdataVal={};
                  for(let key in CRUDJsonData[i]){
                    if(key!="columns"){
                      newdataVal[key]=CRUDJsonData[i][key];
                    }
                  }
                  CRUDJsonData[i]=newdataVal
                  this.loadingMessage="生成表单"+CRUDJsonData.length+'个 执行中...';
                }catch(e){
                  console.log(e);
                  hasError=true;
                  this.loadingMessage="生成表单"+CRUDJsonData.length+'个 执行失败';
                  break;
                }
              }
              if(hasError){
                this.tipMessage="执行失败"
                this.errorType=true;
              }else{
                this.loadingMessage="生成表单"+CRUDJsonData.length+'个 执行完成';
                this.stepIndex=3
                this.submitMessage="提交表单数据中 执行中..."
                saveFormbuild(CRUDJsonData).then(result=>{
                  if(result.code==200){
                    this.tipMessage="执行成功 点击确认自动刷新菜单"
                    this.submitMessage="提交表单数据 执行完成"
                    this.stepIndex=4
                    this.needGenFromData=[]
                    this.isFinish=true;
                  }
                },err=>{
                  this.stepIndex=4
                  this.tipMessage="执行失败"
                  this.submitMessage="提交表单数据失败"
                  this.errorType=true;
                })
              }
            }
          }else{
            this.isFinish=true;
            this.isSavingBtn=true;
            this.stepIndex=4
            this.tipMessage="保存成功 点击确认刷新页面",
            this.submitMessage='CRUD初始化 无需执行';
            this.loadingMessage='生成表单 无需执行';
            this.saveMessage='提交表单数据 无需执行';
          }
        }else{
          this.$message({
            type:'error',
            message:res.msg
          })
          this.stepIndex=1;
          this.tipMessage="执行失败";
          this.saveMessage="CRUD初始化失败";
          this.isSavingBtn=false;
          this.errorType=true;
        }
      })
    },
    // 确认完成批量CRUD作业
    confirmFinish(){
      this.createCrud=false;
      this.isFinish=false;
      this.isSavingBtn=false;
      this.tipMessage="即将执行批量CRUD生成 是否继续?",
      this.submitMessage='CRUD初始化 等待执行';
      this.loadingMessage='生成表单 等待执行';
      this.saveMessage='提交表单数据 等待执行';
      location.reload();
    },
    // 取消
    cancelRetry(){
      this.createCrud=false;
      this.isFinish=false;
      this.isSavingBtn=false;
      this.tipMessage="即将执行批量CRUD生成 是否继续?",
      this.submitMessage='CRUD初始化 等待执行';
      this.loadingMessage='生成表单 等待执行';
      this.saveMessage='提交表单数据 等待执行';
      this.errorType=false;
    },
    // 重试
    retrysaveTree(){
      this.isFinish=false;
      this.tipMessage="即将执行批量CRUD生成 是否继续?",
      this.submitMessage='CRUD初始化 等待执行';
      this.loadingMessage='生成表单 等待执行';
      this.saveMessage='提交表单数据 等待执行';
      this.errorType=false;
      this.continueOperate()
    },
    OptionCardClose(event) {
    	var currentCli = document.getElementById("option-button-group");
    	if (currentCli) {
    		if (!currentCli.contains(event.target)) {
    			this.optionCardShow = false;
    		}
    	}
    },
    // 清空 expandedKeys 数组，使所有节点都处于折叠状态
    collapseAll(data) {
      let self = this;
      data.forEach(item=>{
        self.$refs.leftTree.store.nodesMap[item.menuId].expanded = false;
        if(item.children && item.children.length > 0){
          self.collapseAll(item.children)
        }
      })
    },
    expandAll(data,menuId){
      let self = this;
      data.forEach((item) => {
        if(menuId){
          if(item.menuId==menuId){
            self.$refs.leftTree.store.nodesMap[item.menuId].expanded = true;
          }
        }else{
          self.$refs.leftTree.store.nodesMap[item.menuId].expanded = true;
        }
        item.children && item.children.length > 0
          ? self.expandAll(item.children)
          : ""; // 子级递归
      });
    },
    scrollToNode() {
      let that=this;
      that.$nextTick(()=>{
        let nowNodeEl=document.getElementsByClassName('is-current')[0]
        nowNodeEl.scrollIntoView({behavior: 'smooth', block: 'nearest', inline: 'start'})
      })
    },
  }
}
</script>
<style lang="scss" scoped>
  ::v-deep .el-dialog{
    background: #f4f4f5 !important;
  }
  ::v-deep .el-table .disabled-row {
      background-color: lightgrey !important;
      // pointer-events: none; /* 禁用鼠标事件 */
    }
  ::v-deep .el-tree--highlight-current .el-tree-node.is-current>.el-tree-node__content{
    background-color: #11A983 !important;
    color: white;
  }
  ::v-deep .el-table__body tr.current-row>td.el-table__cell{
    background-color: white !important;
    color: #606266;
  }
  ::v-deep .el-table__body tr{
    height: 20px !important;
  }
  ::v-deep .el-table__body tr.current-row>td.el-table__cell .el-button--text{
    color: #606266;
  }
  ::v-deep .el-dialog:not(.is-fullscreen) {
    top: 10% !important; /* 使用 !important 确保该样式优先级足够高 */
  }
  ::v-deep .el-table th {
    background-color: #304156 !important; /* 设置表头背景颜色 */
    color: white; /* 设置表头文字颜色 */
  }
  ::v-deep .el-table__header th {
    background-color: #304156 !important; /* 设置表头背景颜色 */
    color: white; /* 设置表头文字颜色 */
  }
  ::v-deep .el-button.el-button--text .el-icon-arrow-left {
    font-weight: bold !important;
  }
  ::v-deep .el-button.el-button--text .el-icon-arrow-right {
    font-weight: bold !important;
  }
  ::v-deep .el-button.el-button--text .el-icon-more {
    font-weight: bold !important;
  }
  .middle-transfer-btn{
    height: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
    position: relative;
  }
  // 文件夹卡片
  .folder-box {
  	height: 100%;
  }

  // 右键菜单按钮
  .option-card-button {
  	width: 100%;
  	margin-left: 0;
  	font-size: 14px;
  	border-radius: 0;
  }
  .treeBtn{
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 5px;
    box-sizing: border-box;
    background-color: #304156;
    color: white;
    font-size: 14px;
    width: 100%;
    height: 43px;
    position: absolute;
    left: 0;
    top: 0;
    z-index: 999;
  }
  .treeOperBtn{
    margin: 0px 0 5px !important;
    font-size: 20px !important;
  }
  .activeStep{
    color:#11A983;
  }
  .headbox{
    width: 100%;
    display: flex;
    justify-content: space-between;
  }
  .page-desc{
    display:flex;
    flex-wrap:nowrap;
    justify-content:start;
    align-items: center;
    font-size: 16px;
    margin-bottom: 10px;
    color:darkgrey;
    width: 50%;
  }
  .page-desc-title{
    width: 50%;
    padding-bottom: 5px;
    margin-bottom: 5px;
    color: black;
  }
  .tipStyle{
    width:80%;
    margin-top: 5px;
    margin-left: 20px;
    border-bottom: 1px solid lightgray;
    font-size: 14px;
    padding-bottom: 5px;
    position: relative;
    .iconStyle{
      font-size: 20px;
      color: #11A983;
      position:absolute;
      top: 50%;
      left: -25px;
      transform: translateY(-50%);
    }
  }
  .iconList{
      width: 400px;
      height: 300px;
      overflow-y: scroll;//y轴显示滚动条
      overflow-x: hidden;//x轴溢出隐藏
      display: flex;
      justify-content: space-around;
      flex-wrap: wrap;//一定要换行
      i{
          display: inline-block;
          width: 60px;
          height: 45px;
          color: #000000;
          font-size: 20px;
          border: 1px solid #E6E6E6;
          border-radius: 4px;
          cursor: pointer;
          text-align: center;
          line-height: 45px;
          margin: 5px ;
      }
  }

</style>
